﻿
namespace TFSChangeLog.GeneralUtilities
{
    using System;
    using System.IO;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    using Saxon.Api;

    /// <summary>Summary description for <see cref="XmlTransformUtil"/> class.</summary>
    public static class XmlTransformUtil
    {
        #region Microsoft Transformer
        // TODO: Support Microsoft way of transforming XML file. Remove dependency on SaxonTransofrm
        // public static void Transform(string sXmlPath, string sXslPath)
        // {
        //    try
        //    {
        //        //load the Xml doc
        //        var myXPathDoc = new XPathDocument(sXmlPath);
        //        var myXslTrans = new XslTransform();
        //        //load the Xsl 
        //        myXslTrans.Load(sXslPath);
        //        //create the output stream
        //        var myWriter = new XmlTextWriter
        //            ("GeneratedTFSChangeLog.html", null);
        //        //do the actual transform of Xml
        //        myXslTrans.Transform(myXPathDoc, null, myWriter);
        //        myWriter.Close();
        //    }
        //    catch (Exception e)
        //    {
        //        Console.WriteLine("XSLT Transformation Error Exception: {0}", e.ToString());
        //    }
        // }
        #endregion  

        /// <summary>Summary description for <c>XmlTransformUtil</c> method.</summary>
        /// <param name="sXmlPath">TODO: Summary description for <c>sXmlPath</c> parameter of type <c>string</c>.</param>
        /// <param name="sXslPath">TODO: Summary description for <c>sXslPath</c> parameter of type <c>string</c>.</param>
        public static void SaxonTransform(string sXmlPath, string sXslPath)
        {
            var processor = new Processor();

            string applicationPath = Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

            Uri sXmlPathURI;

            if (TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.tfsChangeLogOuputDirectory != null)
            {
                sXmlPathURI =
                    GenerateURI(
                        Path.GetDirectoryName(TFSChangeLog.DataAccess.TFSChangeLogStaticConfigs.TFSChangeLogXMLFileName));
            }
            else
            {
                sXmlPathURI = GenerateURI(applicationPath);                
            }

            var input = processor.NewDocumentBuilder().Build(new Uri(sXmlPathURI, Path.GetFileName(sXmlPath)));

            var sXslPathURI = GenerateURI(applicationPath);
            var transformer = processor.NewXsltCompiler().Compile(new Uri(sXslPathURI, Path.GetFileName(sXslPath))).Load();

            transformer.InitialContextNode = input;

            var serializer = new Serializer();
            serializer.SetOutputWriter(new StreamWriter(DataAccess.TFSChangeLogStaticConfigs.TFSChangeLogHTMLFileName));

            transformer.Run(serializer);
        }

        /// <summary>Summary description for <c>XmlTransformUtil</c> method.</summary>
        /// <param name="samplesPath">TODO: Summary description for <c>samplesPath</c> parameter of type <c>string</c>.</param>
        /// <returns>TODO: returns an object of type <c>System.Uri</c>.</returns>
        public static Uri GenerateURI(string samplesPath)
        {
            Uri samplesDir;
            if (samplesPath != null)
            {
                if (samplesPath.StartsWith("file:///"))
                {
                    samplesPath = samplesPath.Substring(8);
                }
                else if (samplesPath.StartsWith("file:/"))
                {
                    samplesPath = samplesPath.Substring(6);
                }
            }
            else
            {
                string home = Environment.GetEnvironmentVariable("SAXON_HOME");
                if (home == null)
                {
                    Console.WriteLine("ERROR                  : No input directory supplied, and SAXON_HOME is not set");
                    return null;
                }
                else
                {
                    if (!(home.EndsWith("/") || home.EndsWith("\\")))
                    {
                        home = home + "/";
                    }

                    samplesPath = home + "samples/";
                }
            }

            if (!(samplesPath.EndsWith("/") || samplesPath.EndsWith("\\")))
            {
                samplesPath = samplesPath + "/";
            }

            try
            {
                samplesDir = new Uri(samplesPath);
            }
            catch
            {
                Console.WriteLine("ERROR                  : Invalid URI for samples directory \"{0}\"", samplesPath);
                return null;
            }

            return samplesDir;
        }
    }
}
